#include <asm/io.h>

#define uintptr_t unsigned long int

//定义幻数
#define HISPORT_IOC_MAGIC 'h'
#define HISPORT_INIT _IOW(HISPORT_IOC_MAGIC, 0, int)
#define HISPORT_WRITE _IOW(HISPORT_IOC_MAGIC, 1, int)
#define HISPORT_READ _IOWR(HISPORT_IOC_MAGIC, 2, int)

// 错误码
#define EOK 0
#define EFAIL (-200)
#define EREAD (-201)
#define EWRITE (-202)
#define ETIMEOUT (-203)
#define EPARA (-204)
#define EDATA (-205)
#define ECOPY (-206)
#define EI2CBUS (-207)
#define EI2CACK (-208)
#define ERECVFIFO (-209)

// 偏移相关
#define CHANNEL_ID_OFFSET 24
#define ADDR_OFFSET 16
#define BIT_PER_BYTE 8

// 总线相关
#define MAX_BUS_NUM 128                             /* 目前只支持4路hisport */

// i2c地址掩码
#define I2C_7BIT_MAX_ADDR 0x7F
#define I2C_7BIT_ADDR_MASK I2C_7BIT_MAX_ADDR
#define I2C_RSERVED_EXTERN_LEN 4                    /* 读写buffer的保留字段，其中一个长度用于smbus的crc校验 */
#define I2C_READ_TX_LEN 2                           /* 进行i2c读操作时，需要发送tx_buffer，其长度固定为2 */
#define SDA_HOLD_MASK 0xFFFFFFU
#define SDA_HOLD_RATIO_MASK 0xFFU

#define MCU_ADDR 100
#define HISPORT_BUS_ID_ADD 12
#define MAX_DATA_LEN 1024
#define DEFAULT_REG_NUM 10
#define DEFAULT_FLAG_NUM 2
#define DEFAULT_BATCH_LEN 2
#define DEFAULT_OFFSET_WIDTH 2
#define DEFAULT_LENGTH_WIDTH 2

#define I2C_MASTER_INIT             BIT(1)              // 总线初始化为master
#define I2C_STANDARD_SPEED          BIT(2)              // 总线初始化为标准速率模式(100k)
#define I2C_FORCE_INIT              BIT(9)              // 不管之前有没有初始化，强制初始化总线

// 日志级别
enum {
    DLOG_ERROR = 0,
    DLOG_DEBUG,
    DLOG_INFO
};

// 定义hisport和i2c的结构体
typedef struct tag_hisport_init_s {
    uint32_t bus_num;
    uint32_t reg_num;
    uint32_t flag_num;
    uint32_t send_reg_addr;
    uint32_t recv_reg_addr;
    uint32_t flag_reg_addr;
    uint32_t max_batch_len;
    uint32_t max_data_len;
    uint32_t max_offset_width;
    uint32_t max_length_width;
} STRUCT_INIT;

typedef struct tag_hisport_s {
    uint32_t bus_id;                /* hisport总线的编号，取值范围为0~(MAX_BUS_NUM-1) */
    uint32_t addr;                  /* 器件地址 */
    uint32_t offset;                /* 偏移地址 */
    const uint8_t *tx_buffer;       /* 读操作发送的数据 */
    uint32_t tx_len;                /* 发送命令中数据长度 */
    uint8_t *rx_buffer;             /* 回传数据 */
    uint32_t rx_len;                /* 回传数据长度 */
    uint8_t offset_width;
    uint8_t data_width;
    uint8_t rw_flag;
    int32_t re_read_cnt;            /* 重读次数 */
    int32_t re_write_cnt;           /* 重写次数 */
    uint8_t write_delay;            /* 写操作后是否进行延时，单位：ms */
} STRUCT_DATA;

typedef struct tag_i2c_kmsg_s {
    unsigned short addr;            /* 消息目的地址 */
    unsigned short flags;           /* 消息属性 */
    unsigned char protocol;         /* SMBus消息协议号，仅smbus消息时该字段有效 */
    unsigned char recvd_crc;
    unsigned char quick_cmd;
    unsigned char quick_write;
    unsigned int retries;           /* 通信失败后，若具备重传条件，重传次数 */
    unsigned long timeout;          /* 消息收发超时时间，以jiffies为单位 */
    unsigned int cmd_len;
    unsigned int outstanding;
    unsigned int rcnt;
    unsigned int wcnt;
    unsigned int wlen;              /* 消息发送长度 */
    unsigned char *wbuf;            /* 消息发送缓存 */
    unsigned int rlen;              /* 具有I2C_KMSG_RECV_LEN标识时表示消息接收buffer长度，
                                    否则表示想要接收的消息的长度 */
    unsigned char *rbuf;            /* 消息接收缓存 */
} i2c_kmsg;

typedef struct tag_i2c_kdepl_s {
    unsigned long flags;
    unsigned int sda_hold;
    unsigned int sda_hold_ratio;
    unsigned int scl_high;
    unsigned int scl_low;
    unsigned int scl_low_timeout;
    unsigned int sda_low_timeout;
    unsigned int slave_dlen;
    unsigned short clk_strech_timeout;
    unsigned short slave_address;
} i2c_kdepl;
